package com.elder.business.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.elder.business.domain.*;
import com.elder.business.mapper.*;
import com.elder.common.core.domain.AjaxResult;
import com.elder.common.core.page.TableDataInfo;
import com.elder.common.core.redis.RedisCache;
import com.elder.common.enums.ApartmentType;
import com.elder.common.enums.ApplyStatus;
import com.elder.common.enums.BedType;
import com.elder.common.enums.RoomType;
import com.elder.common.utils.DateUtils;
import com.elder.common.utils.IntegerUtils;
import com.elder.common.utils.StringNewUtils;
import com.elder.common.utils.uuid.SnowGenerator;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.elder.business.service.IApartmentRoomInfoService;

/**
 * 公寓房间信息Service业务层处理
 * 
 * @author elder
 * @date 2023-11-26
 */
@Service
public class ApartmentRoomInfoServiceImpl implements IApartmentRoomInfoService 
{
    @Autowired
    private ApartmentRoomInfoMapper apartmentRoomInfoMapper;
    @Autowired
    private ElderlyApartmentBedsMapper elderlyApartmentBedsMapper;
    @Autowired
    private ElderlyInfoMapper elderlyInfoMapper;
    @Autowired
    private ElderlyapartmentMapper elderlyapartmentMapper;
    @Autowired
    private ApartmentDictMapper apartmentDictMapper;
    @Autowired
    private MemberInfoMapper memberInfoMapper;
    @Autowired
    private RedisCache redisCache;
    /**
     * 查询公寓房间信息
     * 
     * @param id 公寓房间信息主键
     * @return 公寓房间信息
     */
    @Override
    public JSONObject selectApartmentRoomInfoById(Long id)
    {
        ApartmentRoomInfo apartmentRoomInfo = apartmentRoomInfoMapper.selectApartmentRoomInfoById(id);
//        MemberInfo memberInfo = Objects.isNull(apartmentRoomInfo.getNurseId())? null : memberInfoMapper.getMemberByMemberId(apartmentRoomInfo.getNurseId());
        JSONObject obj = new JSONObject();
        obj.put("id",StringNewUtils.long2Str(apartmentRoomInfo.getId()));
        obj.put("apartmentId",StringNewUtils.long2Str(apartmentRoomInfo.getApartmentId()));
        obj.put("roomCode",apartmentRoomInfo.getRoomCode());
        obj.put("roomId",StringNewUtils.long2Str(apartmentRoomInfo.getRoomId()));
        obj.put("roomType",apartmentRoomInfo.getRoomType());
        obj.put("baseFacilities",apartmentRoomInfo.getBaseFacilities());
        obj.put("roomDescribe",apartmentRoomInfo.getRoomDescribe());
        obj.put("roomStatus",apartmentRoomInfo.getRoomStatus());
        obj.put("roomSex",apartmentRoomInfo.getRoomSex());
        obj.put("nurseId",StringNewUtils.formatStr(apartmentRoomInfo.getNurseId()));
        return obj;
    }

    /**
     * 查询公寓房间信息列表
     *公寓房间信息
     * @return 公寓房间信息
     */
    @Override
    public JSONArray selectApartmentRoomInfoList(Long apartmentId, Integer roomType, Integer roomStutas, Integer pageNum, Integer pageSize)
    {
        //分页 获取房间信息
        PageHelper.startPage(pageNum,pageSize);
        List<ApartmentRoomInfo> list = apartmentRoomInfoMapper.getApartmentRoomInfo(apartmentId,roomType,roomStutas);
        PageInfo<ApartmentRoomInfo> pageInfo = new PageInfo<>(list);
        List<ApartmentRoomInfo> roomInfoList = pageInfo.getList();

        //获取字典信息
        List<ApartmentDict> dictList = apartmentDictMapper.getApartmentDictAllInfo();
        Map<Integer, Map<Integer, String>> dictMap = dictList.stream().filter(rel -> Objects.nonNull(rel.getSuperCode()))
                .collect(Collectors.groupingBy(ApartmentDict::getSuperCode, Collectors.toMap(ApartmentDict::getCode, ApartmentDict::getName)));
        //获取公寓名称
        List<Elderlyapartment> apartmentInfo = elderlyapartmentMapper.getAllApartmentInfo();
        Map<Long, String> apartMap = apartmentInfo.stream().collect(Collectors.toMap(Elderlyapartment::getApartmentId, Elderlyapartment::getApartmentName));
        //获取memberId
        List<Long> nurseIds = roomInfoList.stream().map(ApartmentRoomInfo::getNurseId).collect(Collectors.toList());
        Map<Long, String> memberMap = CollectionUtils.isEmpty(nurseIds)? new HashMap<>() :
                (memberInfoMapper.getMemberListByMemberIds(nurseIds).stream().collect(Collectors.toMap(MemberInfo::getMemberId,MemberInfo::getMemberName)));
        JSONArray result = new JSONArray();
        JSONObject obj = null;
        for(ApartmentRoomInfo dto:roomInfoList){
            obj = new JSONObject();
            obj.put("id",StringNewUtils.long2Str(dto.getId()));
            obj.put("apartmentId",StringNewUtils.long2Str(dto.getApartmentId()));
            obj.put("apartmentName",apartMap.get(dto.getApartmentId()));
            obj.put("roomId",StringNewUtils.long2Str(dto.getRoomId()));
            obj.put("roomCode",dto.getRoomCode());
            obj.put("roomType",Objects.isNull(dto.getRoomType())?"":dictMap.get(ApartmentType.ROOM_TYPE.getValue()).get(dto.getRoomType()));
            obj.put("baseFacilities",dto.getBaseFacilities());
            obj.put("describe",dto.getRoomDescribe());
            obj.put("roomStatus",Objects.isNull(dto.getRoomStatus())?"":dictMap.get(ApartmentType.ROOM_STATUS.getValue()).get(dto.getRoomStatus()));
            obj.put("nurseId",StringNewUtils.formatStr(dto.getNurseId()));
            obj.put("nurseName",Objects.isNull(memberMap.get(dto.getNurseId()))?"":memberMap.get(dto.getNurseId()));
            result.add(obj);
        }
        return result;
    }

    /**
     * 新增公寓房间信息
     * 
     * @param apartmentRoomInfo 公寓房间信息
     * @return 结果
     */
    @Override
    public int insertApartmentRoomInfo(ApartmentRoomInfo apartmentRoomInfo)
    {
        apartmentRoomInfo.setId(SnowGenerator.getId());
        apartmentRoomInfo.setRoomId(SnowGenerator.getId());
        apartmentRoomInfo.setCreateTime(DateUtils.getLongTime());
        apartmentRoomInfo.setUpdateTime(DateUtils.getLongTime());
        return apartmentRoomInfoMapper.insertApartmentRoomInfo(apartmentRoomInfo);
    }

    /**
     * 修改公寓房间信息
     * 
     * @param apartmentRoomInfo 公寓房间信息
     * @return 结果
     */
    @Override
    public int updateApartmentRoomInfo(ApartmentRoomInfo apartmentRoomInfo)
    {
        redisCache.deleteObject("NURSE_ROOM_INFO");
        apartmentRoomInfo.setUpdateTime(DateUtils.getLongTime());
        return apartmentRoomInfoMapper.updateApartmentRoomInfo(apartmentRoomInfo);
    }

    /**
     * 批量删除公寓房间信息
     * 
     * @param ids 需要删除的公寓房间信息主键
     * @return 结果
     */
    @Override
    public int deleteApartmentRoomInfoByIds(Long[] ids)
    {
        return apartmentRoomInfoMapper.deleteApartmentRoomInfoByIds(ids);
    }

    /**
     * 删除公寓房间信息信息
     * 
     * @param id 公寓房间信息主键
     * @return 结果
     */
    @Override
    public int deleteApartmentRoomInfoById(Long id)
    {
        return apartmentRoomInfoMapper.deleteApartmentRoomInfoById(id);
    }

    /***
     * @description  房间信息 可根据公寓 房间状态 类型查询
     * @param roomType
     * @param roomStatus
     * @param pageNum
     * @param pageSize
     * @return JSONArray
     * @author zyk
     * @date 2023/12/4 20:48
     */
    @Override
    public JSONObject getElderRoomBedInfo(Long apartmentId, Integer roomType, Integer roomStatus, Integer pageNum, Integer pageSize) {
        //分页
        PageHelper.startPage(pageNum, pageSize);
        List<ApartmentRoomInfo> list = apartmentRoomInfoMapper.getApartmentRoomInfo(apartmentId,roomType,roomStatus);
        PageInfo<ApartmentRoomInfo> page = new PageInfo<>(list);
        List<ApartmentRoomInfo> roomInfoList = page.getList();

        //获取roomIds 用于获取床位信息
        List<Long> roomIds = roomInfoList.stream().map(ApartmentRoomInfo::getRoomId).collect(Collectors.toList());
        List<ElderlyApartmentBeds> bedInfoList = elderlyApartmentBedsMapper.getElderRoomBedInfo(roomIds);
        Map<Long, List<ElderlyApartmentBeds>> bedMap = bedInfoList.stream().collect(Collectors.groupingBy(ElderlyApartmentBeds::getRoomId, Collectors.toList()));

        List<Long> elderIds = bedInfoList.stream().filter(rel -> Objects.nonNull(rel.getElderId())).distinct().map(ElderlyApartmentBeds::getElderId).collect(Collectors.toList());
        //获取居住人员
        List<ElderlyInfo> elderInfoList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(elderIds)) {
            elderInfoList = elderlyInfoMapper.getElderInfoByElderIds(elderIds);
        }
        Map<Long, ElderlyInfo> elderlyInfoMap = elderInfoList.stream().collect(Collectors.toMap(ElderlyInfo::getElderId, ElderlyInfo -> ElderlyInfo));

        //获取字典信息
//        List<ApartmentDict> dictList = apartmentDictMapper.getApartmentDictAllInfo();
//        Map<Integer, Map<Integer, String>> dictMap = dictList.stream().filter(rel -> Objects.nonNull(rel.getSuperCode()))
//                .collect(Collectors.groupingBy(ApartmentDict::getSuperCode, Collectors.toMap(ApartmentDict::getCode, ApartmentDict::getName)));
        Map<Integer, String> roomTypeMap = apartmentDictMapper.getApartmentDictInfo(1)
                .stream().collect(Collectors.toMap(ApartmentDict::getCode, ApartmentDict::getName));
        //获取memberId
        List<Long> nurseIds = roomInfoList.stream().filter(rel -> Objects.nonNull(rel.getNurseId())).map(ApartmentRoomInfo::getNurseId).collect(Collectors.toList());
        Map<Long, String> memberMap = CollectionUtils.isEmpty(nurseIds)? new HashMap<>() :
                (memberInfoMapper.getMemberListByMemberIds(nurseIds).stream().collect(Collectors.toMap(MemberInfo::getMemberId,MemberInfo::getMemberName)));

        //获取公寓信息
        List<Elderlyapartment> apartmentInfo = elderlyapartmentMapper.getAllApartmentInfo();
        Map<Long, String> apartMap = apartmentInfo.stream().collect(Collectors.toMap(Elderlyapartment::getApartmentId, Elderlyapartment::getApartmentName));
        JSONArray result = new JSONArray();
        JSONObject obj = null;
        for(ApartmentRoomInfo dto : roomInfoList){
            obj = new JSONObject();
            obj.put("Id",StringNewUtils.long2Str(dto.getId()));
            obj.put("apartmentId",StringNewUtils.long2Str(dto.getApartmentId()));
            obj.put("apartmentName",apartMap.get(dto.getApartmentId()));
            obj.put("roomId", StringNewUtils.long2Str(dto.getRoomId()));
            obj.put("roomCode",dto.getRoomCode());
            if(CollectionUtils.isEmpty(bedMap.get(dto.getRoomId()))){
                obj.put("elder",new ArrayList<>());
            }else {
                List<JSONObject> elder = bedMap.get(dto.getRoomId()).stream().map(v -> {
                    JSONObject o = new JSONObject();
                    o.put("roomCode",dto.getRoomCode());
                    o.put("elderId", Objects.isNull(v.getElderId()) ? "" : v.getElderId());
                    o.put("elderName", Objects.isNull(v.getElderId()) ? "" : elderlyInfoMap.get(v.getElderId()).getElderName());
                    o.put("sex", Objects.isNull(v.getElderId()) ? "" : elderlyInfoMap.get(v.getElderId()).getElderGender());
                    o.put("bedCode", StringNewUtils.isEmpty(v.getBedCode()) ? "" : v.getBedCode());
                    o.put("bedStatus", BedType.getCnName(v.getBedStatus()));
                    return o;
                }).collect(Collectors.toList());
                obj.put("elder",elder);
            }
            obj.put("describe",StringNewUtils.isEmpty(dto.getRoomDescribe())?"":dto.getRoomDescribe());
            obj.put("baseFacilities",StringNewUtils.isEmpty(dto.getBaseFacilities()) ?"":dto.getBaseFacilities());
            obj.put("roomType",roomTypeMap.get(dto.getRoomType()));
            obj.put("roomStatus", RoomType.getCnName(dto.getRoomStatus()));
            obj.put("roomSex",dto.getRoomSex());
            obj.put("nurseId",StringNewUtils.formatStr(dto.getNurseId()));
            obj.put("nurseName",Objects.isNull(memberMap.get(dto.getNurseId()))?"":memberMap.get(dto.getNurseId()));
            result.add(obj);
        }
        JSONObject rel = new JSONObject();
        rel.put("code",200);
        rel.put("data",result);
        rel.put("pageNum",page.getPages());
        rel.put("pageSize",page.getSize());
        rel.put("total",page.getTotal());
        return rel;
    }

    /***
     * @description  获取最新的房间价格信息
     * @return JSONObject
     * @author zyk
     * @date 2023/12/23 10:15
     */
    @Override
    public TableDataInfo getRoomNewPriceInfo() {
        //获取最新的房间价格
        List<ApartmentRoomPrice> roomPriceList = apartmentRoomInfoMapper.getRoomPriceInfo();
        Map<Integer, String> dictMap = apartmentDictMapper.getApartmentDictInfo(ApartmentType.ROOM_TYPE.getValue()).stream()
                .collect(Collectors.toMap(ApartmentDict::getCode, ApartmentDict::getName));
        List<JSONObject> list = roomPriceList.stream().map(v -> {
            JSONObject obj = new JSONObject();
            obj.put("roomPriceId", StringNewUtils.long2Str(v.getRoomPriceId()));
            obj.put("roomType", v.getRoomType());
            obj.put("roomTypeName", dictMap.get(v.getRoomType()));
            obj.put("roomRemark", v.getRoomRemark());
            obj.put("roomPrice", v.getRoomPrice());
            obj.put("nurseContent", v.getNurseContent());
            obj.put("applyStatus", ApplyStatus.getCnName(v.getApplyStatus()));
            return obj;
        }).collect(Collectors.toList());
        TableDataInfo result = new TableDataInfo();
        result.getDataTable(list);
        return result;
    }

    @Override
    public TableDataInfo getApartmentRoomPriceList(Long createTime,String applyStatus) {
        List<ApartmentRoomPrice> roomPriceList = apartmentRoomInfoMapper.getApartmentRoomPriceList(createTime,ApplyStatus.getValue(applyStatus));
        Map<Integer, String> dictMap = apartmentDictMapper.getApartmentDictInfo(ApartmentType.ROOM_TYPE.getValue()).stream()
                .collect(Collectors.toMap(ApartmentDict::getCode, ApartmentDict::getName));
        List<JSONObject> objectList = roomPriceList.stream().map(v -> {
            JSONObject obj = new JSONObject();
            obj.put("roomPriceId", StringNewUtils.long2Str(v.getRoomPriceId()));
            obj.put("roomType", dictMap.get(v.getRoomType()));
            obj.put("roomRemark", v.getRoomRemark());
            obj.put("roomPrice", v.getRoomPrice());
            obj.put("nurseContent", v.getNurseContent());
            obj.put("createTime",DateUtils.dateStr(v.getCreateTime()));
            obj.put("applyStatus", ApplyStatus.getCnName(v.getApplyStatus()));
            return obj;
        }).collect(Collectors.toList());
        TableDataInfo result = new TableDataInfo();
        result.setCode(200);
        result.setMsg("success");
        result.setRows(objectList);
        return result;
    }


    /***
     * @description 修改房间定价信息
     * @param roomPriceId
     * @param roomRemark
     * @param roomPrice
     * @param nurseContent
     * @param applyStatus
     * @return AjaxResult
     * @author zyk
     * @date 2023/12/11 21:16
     */
    @Override
    public AjaxResult updateRoomPriceInfo(Long roomPriceId,String roomRemark,String roomPrice,String nurseContent,String applyStatus) {
        apartmentRoomInfoMapper.updateRoomPriceInfo(roomPriceId,roomRemark,roomPrice,nurseContent,ApplyStatus.getValue(applyStatus));
        return AjaxResult.success();
    }

    /***
     * @description 添加申请房间定价
     * @param apartmentRoomPrice
     * @return AjaxResult
     * @author zyk
     * @date 2023/12/11 21:15
     */
    @Override
    public AjaxResult addRoomPriceInfo(ApartmentRoomPrice apartmentRoomPrice) {
        apartmentRoomPrice.setRoomPriceId(SnowGenerator.getId());
        apartmentRoomPrice.setCreateTime(DateUtils.getLongTime());
        apartmentRoomPrice.setApplyStatus(ApplyStatus.APPLUING.getValue());
        apartmentRoomInfoMapper.addRoomPriceInfo(apartmentRoomPrice);
        return AjaxResult.success();
    }

    @Override
    public TableDataInfo getRoomInfo() {
        List<JSONObject> roomInfo = redisCache.getCacheList("roomInfo");
        if(CollectionUtils.isNotEmpty(roomInfo)){
            return new TableDataInfo().getDataTable(roomInfo);
        }
        List<ApartmentRoomInfo> roomInfoList = apartmentRoomInfoMapper.getRoomInfoList();
        List<ApartmentDict> dictInfo = apartmentDictMapper.getApartmentDictInfo(ApartmentType.ROOM_TYPE.getValue());
        Map<Integer, String> roomMap = dictInfo.stream().collect(Collectors.toMap(ApartmentDict::getCode, ApartmentDict::getName));
        List<JSONObject> objectList = roomInfoList.stream().map(v -> {
            JSONObject obj = new JSONObject();
            obj.put("id", StringNewUtils.long2Str(v.getId()));
            obj.put("roomId", StringNewUtils.long2Str(v.getRoomId()));
            obj.put("roomCode", v.getRoomCode());
            obj.put("roomType", roomMap.get(v.getRoomType()));
            obj.put("roomStatus", RoomType.getCnName(v.getRoomStatus()));
            obj.put("nurseId", StringNewUtils.long2Str(v.getNurseId()));
            obj.put("apartmentId", StringNewUtils.long2Str(v.getApartmentId()));
            return obj;
        }).collect(Collectors.toList());
        redisCache.setCacheList("roomInfo",objectList);
        return new TableDataInfo().getDataTable(objectList);
    }

    @Override
    public TableDataInfo getNurseRoomInfo() {
        TableDataInfo result = new TableDataInfo();
        List<JSONObject> info = redisCache.getCacheList("NURSE_ROOM_INFO");
        if(CollectionUtils.isNotEmpty(info)){
                result.setRows(info);
            return result;
        }
        List<ApartmentRoomInfo> roomInfoList = apartmentRoomInfoMapper.getNurseRoomInfoList();
        if(CollectionUtils.isEmpty(roomInfoList)){
            result.setRows(new ArrayList<>());
            return result;
        }
        List<JSONObject> objectList = roomInfoList.stream().map(v -> {
            JSONObject obj = new JSONObject();
            obj.put("roomId", StringNewUtils.formatStr(v.getRoomId()));
            obj.put("roomCode", v.getRoomCode());
            obj.put("roomSex", v.getRoomSex());
            return obj;
        }).collect(Collectors.toList());
        redisCache.setCacheList("NURSE_ROOM_INFO",objectList);
        result.setRows(objectList);
        return result;
    }
}
